package de.openkanban.server.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.openkanban.server.dao.UserDao;
import de.openkanban.server.domain.User;
import de.openkanban.shared.util.StatusCodes;

/**
 * jpa implementation of user data access object
 */
@Repository
public class UserDaoImpl implements UserDao {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public boolean authentificate(User user) {
		Query query = entityManager.createQuery("SELECT u FROM User u WHERE email=:email AND password=:password");
		query.setParameter("email", user.getEmail());
		query.setParameter("password", user.getPassword());
		@SuppressWarnings("unchecked")
		List<User> ul = (List<User>) query.getResultList();
		if (ul.isEmpty()) {
			return false;
		}
		user.setUserId(ul.get(0).getUserId());
		return true;
	}

	@Override
	@Transactional
	public User createUser(User user) {
		entityManager.persist(user);
		return user;
	}

	public String test() {
		return "test";
	}

	@Override
	public User getUser(Long id) {
		return entityManager.find(User.class, id);
	}

	@Override
	@SuppressWarnings("unchecked")
	public User getUser(String eMail) {
		Query query = entityManager.createQuery("SELECT u FROM User u WHERE email=:email");
		query.setParameter("email", eMail);
		List<User> user = query.getResultList();
		if (user == null || user.size() < 1) {
			return null;
		}
		return user.iterator().next();
	}

	@Override
	public User[] getContacts(Long userId) {

		User parentUser = getUser(userId);
		if (parentUser.getKontakteEmailList() == null) {
			return null;
		}

		return parentUser.getKontakteEmailList().toArray(new User[] {});

	}

	@Override
	@Transactional
	public StatusCodes addContact(String parentUserId, String eMail) {
		User user = getUser(Long.parseLong(parentUserId));
		User contact = getUser(eMail);

		if (contact == null) {
			return StatusCodes.INVALID_INPUT_DATA;
		}

		if (contact != null && user != null) {
			if (user.getKontakteEmailList().contains(contact)) {
				return StatusCodes.DUPLICATE_ENTRY;
			}

			user.addContact(contact);
			entityManager.merge(user);
			return StatusCodes.OK;
		}
		return StatusCodes.DATABASE_ERROR;
	}

	@Override
	@Transactional
	public StatusCodes removeContact(User user, String eMail) {
		User parentUser = entityManager.find(User.class, user.getUserId());
		
		User contact = getUser(eMail);

		if (contact != null) {
			if (parentUser.removeContact(contact)) {
				entityManager.merge(parentUser);
				return StatusCodes.OK;
			} else{
				return StatusCodes.FEHLER_BEIM_ENTFERNEN;
			}
		}
		return StatusCodes.DATABASE_ERROR;
	}

	@Override
	@Transactional
	public StatusCodes updateUser(User user) {
		entityManager.merge(user);
		return StatusCodes.OK;
	}

}
